package com.wispx.gateway.core.helper;

import com.wispx.gateway.config.pojo.ServiceDefinition;
import com.wispx.gateway.core.request.GatewayRequest;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.http.*;

import java.net.InetSocketAddress;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;

/**
 * netty、网关、asyncHttpClient 请求之间的转换
 */
public class GatewayRequestHelper {

    private GatewayRequestHelper() {

    }

    /**
     * netty的请求转化为网关的请求
     *
     * @return 网关请求
     */
    public static GatewayRequest buildGatewayRequest(ServiceDefinition serviceDefinition, ChannelHandlerContext ctx, FullHttpRequest request) {
        HttpHeaders headers = request.headers(); // headers
        String host = headers.get(HttpHeaderNames.HOST); // host
        CharSequence mimeType = HttpUtil.getMimeType(request);
        String contentType = mimeType == null ? null : mimeType.toString(); // content-type
        HttpMethod method = request.method(); // 请求方式 GET/POST/PUT
        String uri = request.uri(); // uri
        String clientIp = getClientIp(ctx, request); // 原始客户端 IP
        Charset charset = HttpUtil.getCharset(request, StandardCharsets.UTF_8);// 字符集
        return new GatewayRequest(
                serviceDefinition,
                charset,
                clientIp,
                host,
                uri,
                method,
                contentType,
                headers,
                request);
    }

    // 获取原始客户端的IP
    private static String getClientIp(ChannelHandlerContext ctx, FullHttpRequest request) {
        // X-Forwarded-For: 客户端IP, 代理1IP, 代理2IP, ...
        String xForwardFor = request.headers().get("X-Forwarded-For");
        if (xForwardFor != null && !xForwardFor.isEmpty()) {
            String[] ips = xForwardFor.split("\\.");
            if (ips != null && ips.length >= 1) {
                return ips[0];
            }
        }
        // 没有X-Forwarded-For头，取直连客户端的地址（可能是原始IP，也可能是代理IP）
        InetSocketAddress address = (InetSocketAddress) ctx.channel().remoteAddress();
        return address.getAddress().getHostAddress();
    }


}
